using System;
using System.Collections.Generic;
using System.Text;

public class TokenString
{
    private string[] _elements;

    public delegate string NextLineFn();

    // Tokenize the passed string.
    public TokenString(string strInput, NextLineFn nextLineFn, bool bIgnoreMissingQuote)
    {
        List<String> elements = new List<string>();

        bool firstChar = true;
        char quoteChar;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < strInput.Length; i++)
        {
            // If the first character is a quote then look for the matching quote
            if (firstChar && (strInput[i] == '"' || strInput[i] == '\''))
            {
                quoteChar = strInput[i];
                for (i++; ; i++)
                {
                    if (i >= strInput.Length)
                    {
                        if (nextLineFn == null)
                        {
                            if (bIgnoreMissingQuote)
                                break;
                            else
                                throw new Exception("Unclosed quote in line");
                        }
                        else
                        {
                            string strNextLine = nextLineFn();
                            if (strNextLine == null)
                                if (bIgnoreMissingQuote)
                                    break;
                                else
                                    throw new Exception("Unclosed quote in line");
                            strInput += "\n" + strNextLine;
                        }
                    }
                    if (strInput[i] == quoteChar)
                    {
                        // Doubled quotes get replaced by a single quote.
                        if (i + 1 == strInput.Length || strInput[i + 1] != quoteChar)
                            break;
                        else
                            i++;
                    }
                    sb.Append(strInput[i]);
                }
            }
            else
            {
                if (strInput[i] != ' ')
                    firstChar = false;
                if ((strInput[i] == '\t') || (strInput[i] == ','))
                {
                    elements.Add(sb.ToString().Trim());
                    sb.Length = 0;
                    firstChar = true;
                }
                else
                    sb.Append(strInput[i]);
            }
        }
        elements.Add(sb.ToString().Trim());
        _elements = elements.ToArray();
    }

    public int TokenCount
    {
        get { return _elements.Length; }
    }

    public string this[int iToken]
    {
        get
        {
            return _elements[iToken];
        }
    }
}
